﻿using System.Diagnostics;
using System.Web;

namespace ReadyApps.Common
{
    class TraceManager
    {
        #region Variables and Constants

        private static TraceComponent enabledComponents = TraceComponent.None;
        private static TraceLevel enabledLevel = TraceLevel.Off;

        #endregion

        #region Properties

        private static bool Enabled
        {
            get { return HttpContext.Current != null; }
        }

        private static TraceContext Context
        {
            get { return HttpContext.Current.Trace; }
        }

        #endregion

        #region Constructor

        static TraceManager()
        {
            enabledComponents = ReadyAppsSettings.EnabledComponents;
            enabledLevel = ReadyAppsSettings.EnabledLevel;
        }

        #endregion

        #region Public Methods

        public static void Write(TraceComponent component, TraceLevel level, string message)
        {
            if (NeedsTracing(component, level))
            {
                if (level > TraceLevel.Warning)
                {
                    Context.Write(string.Format("{0}.{1}", component, level), message);
                }
                else
                {
                    Context.Warn(string.Format("{0}.{1}", component, level), message);
                }
            }
        }

        public static void WriteFormat(TraceComponent component, TraceLevel level, string format, params object[] args)
        {
            if (NeedsTracing(component, level))
            {
                if (level > TraceLevel.Warning)
                {
                    Context.Write(string.Format("{0}.{1}", component, level), string.Format(format, args));
                }
                else
                {
                    Context.Warn(string.Format("{0}.{1}", component, level), string.Format(format, args));
                }
            }
        }

        public static void ParameterValue(TraceComponent component, string parameterName, object parameterValue)
        {
            Write(component, TraceLevel.Info, string.Format(
                "Parameter {0} ({1}): {2}",
                parameterName,
                parameterValue != null ? parameterValue.GetType().ToString() : "null",
                parameterValue));
        }

        public static void VariableValue(TraceComponent component, string variableName, object variableValue)
        {
            Write(component, TraceLevel.Info, string.Format(
                "Variable {0} ({1}): {2}",
                variableName,
                variableValue != null ? variableValue.GetType().ToString() : "null",
                variableValue));
        }

        public static void BeginMethod(TraceComponent component, string methodName)
        {
            Write(component, TraceLevel.Verbose, "Begin " + methodName);
        }

        public static void EndMethod(TraceComponent component, string methodName)
        {
            Write(component, TraceLevel.Verbose, "End " + methodName);
        }

        public static void ExecuteMethod(TraceComponent component, string methodName)
        {
            Write(component, TraceLevel.Verbose, "Execute " + methodName);
        }

        #endregion

        #region Private Methods

        private static bool NeedsTracing(TraceComponent component, TraceLevel level)
        {
            // Only write trace information if the component is in the enabled list, the level is high enough,
            // and the HttpContext trace system is available
            return ((enabledComponents & component) > 0) && (level <= enabledLevel) && Enabled;
        }

        #endregion
    }
}
